package notYet;

import java.util.Iterator;

import processing.core.PApplet;
import toxi.geom.Rect;
import toxi.geom.Vec2D;
import toxi.physics2d.VerletParticle2D;
import toxi.physics2d.VerletPhysics2D;
import toxi.physics2d.VerletSpring2D;

@SuppressWarnings("serial")
public class MC_SoftBodySquare extends PApplet {

	/**
	 * <p>
	 * Softbody square demo is showing how to create a 2D square mesh out of
	 * verlet particles and make it stable enough to avoid total structural
	 * deformation by including an inner skeleton.
	 * </p>
	 * 
	 * <p>
	 * Usage: move mouse to drag/deform the square
	 * </p>
	 */

	/*
	 * Copyright (c) 2008-2009 Karsten Schmidt
	 * 
	 * This demo & library is free software; you can redistribute it and/or
	 * modify it under the terms of the GNU Lesser General Public License as
	 * published by the Free Software Foundation; either version 2.1 of the
	 * License, or (at your option) any later version.
	 * 
	 * http://creativecommons.org/licenses/LGPL/2.1/
	 * 
	 * This library is distributed in the hope that it will be useful, but
	 * WITHOUT ANY WARRANTY; without even the implied warranty of
	 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
	 * General Public License for more details.
	 * 
	 * You should have received a copy of the GNU Lesser General Public License
	 * along with this library; if not, write to the Free Software Foundation,
	 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
	 */

	int DIM = 25;
	int REST_LENGTH = 20;
	float STRENGTH = 0.125f;
	float INNER_STRENGTH = 0.5f;

	VerletPhysics2D physics;
	VerletParticle2D head;
	VerletParticle2D tail;
	VerletSpring2D verletTest1;
	VerletSpring2D verletTest2;

	public void setup() {
		size(1280, 720, "hipstersinc.P5Sunflow");
		smooth();
		physics = new VerletPhysics2D();
		physics.setGravity(new Vec2D(0, 0.3f));
		physics.setWorldBounds(new Rect(0, 0, width, height));
		
		populateWithParticlesAndSprings();
		
		createSkeleton();
		
		//head = physics.particles.get(0);
		head = physics.particles.get((DIM - 1) / 2);
		head.lock();
	}

	private void createSkeleton() {
		VerletParticle2D p = physics.particles.get(0);
		VerletParticle2D q = physics.particles.get(physics.particles.size() - 1);
		float len = sqrt(sq(REST_LENGTH * (DIM - 1)) * 2);
		VerletSpring2D s = new VerletSpring2D(p, q, len, INNER_STRENGTH);
		verletTest1 = s;
		physics.addSpring(s);
		p = physics.particles.get(DIM - 1);
		q = physics.particles.get(physics.particles.size() - DIM);
		s = new VerletSpring2D(p, q, len, INNER_STRENGTH);
		verletTest2 = s;
		physics.addSpring(s);
	}

	private void populateWithParticlesAndSprings() {
		int idx = 0;
		for (int y = 0; y < DIM; y++) {
			for (int x = 0; x < DIM; x++) {
				VerletParticle2D p = new VerletParticle2D(x * REST_LENGTH, y * REST_LENGTH);
				physics.addParticle(p);
				if (x > 0) {
					VerletSpring2D s = new VerletSpring2D(p, physics.particles.get(idx - 1), REST_LENGTH, STRENGTH);
					physics.addSpring(s);
				}
				if (y > 0) {
					VerletSpring2D s = new VerletSpring2D(p, physics.particles.get(idx - DIM), REST_LENGTH, STRENGTH);
					physics.addSpring(s);
				}
				idx++;
			}
		}
	}

	public void draw() {
		background(0);
		stroke(255);
		head.set(mouseX, mouseY);
		physics.update();
		
		for (VerletSpring2D spring : physics.springs) {
			line(spring.a.x, spring.a.y, spring.b.x, spring.b.y);
		}
		
		for(VerletParticle2D particle : physics.particles){
			ellipse(particle.x, particle.y, 3, 3);
		}
	}

	@Override
	public void keyPressed() {
		//System.out.println("key:"+key);
		if(key == ' '){
			INNER_STRENGTH = INNER_STRENGTH + 0.01f;
		} else {
			INNER_STRENGTH = INNER_STRENGTH - 0.01f;
		}
		verletTest1.setStrength(INNER_STRENGTH);
		verletTest2.setStrength(INNER_STRENGTH);
	}

	static public void main(String args[]) {
		PApplet.main(new String[] { "--bgcolor=#FFFFFF", "notYet.MC_SoftBodySquare" });
	}
}
